package com.nmdl.print.utils;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.DialogFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.blankj.utilcode.util.PermissionUtils;
import com.blankj.utilcode.util.StringUtils;
import com.hprt.lib.mt800.HPRTPrinterHelper;
import com.hprt.lib.mt800.PrinterStatus;
import com.hprt.lib.mt800.exception.CustomerCodeException;
import com.hprt.lib.mt800.listener.NameListener;
import com.hprt.lib.mt800.listener.PrinterStateListener;
import com.nmdl.print.MainActivity;
import com.nmdl.print.MyApplication;
import com.nmdl.print.R;

import java.io.File;

public class PrintFragment extends DialogFragment {
    private static final int CONNECT_RESULT = 1000;
    private static final int PRINT_RESULT = 1100;
    private int info_flag = 1;
    private boolean mIsShowAnimation = true;
    private IntentFilter intentFilter;
    private BluetoothReceiver bluetoothReceiver;
    private BluetoothAdapter bluetoothAdapter;
    private PrintStep1Holder printStep1Holder;
    private PrintStep2Holder printStep2Holder;
    private String pdfUrl;//打印的pdf路径
    private File pdfFile;//打印的pdf文件
    private boolean connectRes;//连接打印机结果
    private static final String TAG = "PrintFragment";
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case CONNECT_RESULT:
                    int connect = msg.arg1;
                    if (connect == -1) showShort(R.string.customer_code_error);
                    else showShort(connectRes ? "连接成功！" : "连接失败！");
                    MyApplication.getInstance().setConnectRes(connectRes);
                    if (connectRes) {
                        printStep1Holder.setStep1Visibility(View.GONE);
                        printStep2Holder.setStep2Visibility(View.VISIBLE);
                        getDeviceInfo();
                    }
                    break;
                case PRINT_RESULT:
                    boolean result = (boolean) msg.obj;
                    showShort(result ? "打印成功！" : "打印失败！");
                    printStep2Holder.setPrintBtnEnable(true);
                    break;
            }
        }
    };

    public static PrintFragment newInstance(String pdfUrl) {
        PrintFragment fragment = new PrintFragment();
        Bundle bundle = new Bundle();
        bundle.putString("pdfUrl", pdfUrl);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public void onStart() {
        super.onStart();
        initDialog();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View mRootView = inflater.inflate(getLayoutId(), container, false);
        printStep1Holder = new PrintStep1Holder(mRootView);
        printStep2Holder = new PrintStep2Holder(mRootView);
        initEventAndData();
        return mRootView;
    }

    private int getLayoutId() {
        return R.layout.fragment_print;
    }


    private void initEventAndData() {
//        pdfUrl = getArguments().getString("pdfUrl");
        pdfUrl = "https://www.gjtool.cn/pdfh5/git.pdf";
        initReceiver();
        initBlueTooth();
        //第一步：下载pdf文件
        downPdf();
    }

    private void initBlueTooth() {
        intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        //
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        //
        getActivity().registerReceiver(bluetoothReceiver, intentFilter);
        bluetoothAdapter.enable();
        connectRes = MyApplication.getInstance().isConnectRes();
        if (connectRes) {
            getDeviceInfo();
            printStep1Holder.setStep1Visibility(View.GONE);
            printStep2Holder.setStep2Visibility(View.VISIBLE);
        } else {
            printStep1Holder.setStep1Visibility(View.VISIBLE);
            bluetoothAdapter.startDiscovery();
        }
    }

    private void initReceiver() {
        bluetoothReceiver = new BluetoothReceiver(new BluetoothReceiver.BluetoothListener() {
            @Override
            public void onDiscoveryStart() {
                Log.i(TAG, "onDiscoveryStart");
            }

            @Override
            public void onDeviceFound(BluetoothDevice device) {
                for (BluetoothDevice bluetoothDevice : printStep1Holder.devicesAdapter.getData()) {
                    if (bluetoothDevice.getName().equals(device.getName())) {
                        return;
                    }
                }
                printStep1Holder.devicesAdapter.addData(device);
                bluetoothAdapter.cancelDiscovery();
                Log.i(TAG, "onDeviceFound -> " + device.getName());
            }

            @Override
            public void onDeviceBondStateChange(Integer state) {
                Log.i(TAG, "onDeviceBondStateChange -> " + state);
            }

            @Override
            public void onDeviceLost(BluetoothDevice device) {
                Log.i(TAG, "onDeviceLost 设备丢失 -> " + device);
            }

            @Override
            public void onBluetoothStateChange(Integer state) {
                Log.i(TAG, "onBluetoothStateChange -> " + state);
            }

            @Override
            public void onDiscoveryFinish() {
                Log.i(TAG, "onDiscoveryFinish");
                printStep1Holder.setProgressVisibility(View.INVISIBLE);
                if (printStep1Holder.devicesAdapter.getData().size() <= 0) {
                    showShort("没有找到打印机设备！");
                    printStep1Holder.setRescanVisibility(View.VISIBLE);
                }
            }
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy-------");
        bluetoothAdapter.cancelDiscovery();
        getActivity().unregisterReceiver(bluetoothReceiver);
    }

    private void initDialog() {
        //设置dialog样式
        Dialog dialog = getDialog();
        //dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        //设置window样式
        Window window = dialog.getWindow();
        if (window != null) {
            if (mIsShowAnimation)
                window.getAttributes().windowAnimations = R.style.DatePickerDialogAnim;
            WindowManager.LayoutParams lp = window.getAttributes();
            lp.gravity = Gravity.BOTTOM; // 紧贴底部
            lp.width = WindowManager.LayoutParams.MATCH_PARENT; // 宽度持平
            lp.dimAmount = 0.45f;
            window.setAttributes(lp);
            window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
            //设置背景透明
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        }
    }

    private void showUiMessage(String msg) {
        getActivity().runOnUiThread(() -> showShort(msg));
    }

    private String getResString(int resId) {
        return getResources().getText(resId).toString();
    }

    private void showShort(int resId) {
        showShort(getResources().getText(resId).toString());
    }

    private void showShort(String msg) {
        Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show();
    }

    @SuppressLint("WrongConstant")
    public void downPdf() {
        boolean granted = PermissionUtils.isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (!granted) {
            PermissionUtils.permission(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    .callback(new PermissionUtils.SimpleCallback() {
                        @Override
                        public void onGranted() {
                            downPdf();
                        }

                        @Override
                        public void onDenied() {
                            showShort("权限文件存储申请失败！");
                        }
                    })
                    .request();
            return;
        }
        Download.downLoadFile(pdfUrl, new Download.OnDownBack() {
            @Override
            public void onSuccess(String filePath) {
                showUiMessage("下载PDF文件成功！");
                pdfFile = new File(filePath);
            }

            @Override
            public void onProgress(int progress) {

            }

            @Override
            public void onFail() {
                showUiMessage("下载PDF文件失败！");
            }
        });
    }

    private void getDeviceInfo() {
        if (info_flag == 1)
            HPRTPrinterHelper.INSTANCE.getPrintName(s -> printStep2Holder.setInfoText(s));
        if (info_flag == 2)
            HPRTPrinterHelper.INSTANCE.getPrinterNo(s -> printStep2Holder.setInfoText(s));
        if (info_flag == 3)
            HPRTPrinterHelper.INSTANCE.getFirmwareVersion(s -> printStep2Holder.setInfoText(s));
        if (info_flag == 4)
            HPRTPrinterHelper.INSTANCE.getCarbonNo(s -> printStep2Holder.setInfoText(s));
        if (info_flag == 5)
            HPRTPrinterHelper.INSTANCE.getCarbonSurplus(i -> printStep2Holder.setInfoText(String.valueOf(i)));
        else {
            initStateListener();
            getDeviceState(null);
        }
    }

    private void initStateListener() {
        HPRTPrinterHelper.INSTANCE.attachPrinterStateListener(new PrinterStateListener() {
            @Override
            public void onState(int state) {
                if (getStateListener != null) {
                    getStateListener.backState(PrintUtils.getState(state));
                    getStateListener = null;
                }
            }

            @Override
            public void onBattery(int i) {

            }

            @Override
            public void onStandbyTime(int i) {

            }

            @Override
            public void onDensity(int i) {

            }

            @Override
            public void onMode(int i) {

            }

            @Override
            public void onTemperature(int i) {

            }

            @Override
            public void onPrinterStatus(PrinterStatus printerStatus) {
                getActivity().runOnUiThread(() -> {
                    printStep2Holder.device_electric_tv.setText("电量状态：" + printerStatus.getBattery() + "%");
                    String standByTime = printerStatus.getTime() != 0 ? printerStatus.getTime() + "Min" : "永不关机";
                    printStep2Holder.device_can_time_tv.setText("待机时间：" + standByTime);
                    printStep2Holder.device_print_density_tv.setText("打印浓度：" + PrintUtils.getDensity(printerStatus.getDensity()));
                    printStep2Holder.device_print_model_tv.setText("打印模式：" + (printerStatus.getMode() == 0 ? "热敏纸" : "A4纸"));
                    printStep2Holder.device_temperature_tv.setText("设备温度：" + (printerStatus.getTemperature() + "℃"));
                    printStep2Holder.device_free_tv.setText("是否空闲：" + (printerStatus.isIdle() ? "是" : "否"));
                    printStep2Holder.device_cache_state_tv.setText("缓冲区状态：" + (printerStatus.isBuffIsNull() ? "空" : "非空"));
                    printStep2Holder.device_state_tv.setText("设备状态：" + PrintUtils.getState(printerStatus.getState()));
                });
            }
        });
    }

    private void getDeviceState(GetStateListener getStateListener) {
        HPRTPrinterHelper.INSTANCE.checkState();
        this.getStateListener = getStateListener;
    }

    private void startPrint() {
        getDeviceState(msg -> {
            getActivity().runOnUiThread(() -> {
                if (!msg.equals("打印机就绪")) {
                    showShort(msg);
                    return;
                }
                if (pdfFile != null) {
                    printStep2Holder.setPrintBtnEnable(false);
                    mHandler.post(() -> {
                        Bitmap printBitmap = HPRTPrinterHelper.INSTANCE.pdfToPrintImage(pdfFile, 0);
                        //type ->0:二值, 1：文档, 2:图片, 无参数做二值处理
                        HPRTPrinterHelper.INSTANCE.preparePrint();
                        Boolean result = HPRTPrinterHelper.INSTANCE.printBitmap(printBitmap, 1);
                        Message message = Message.obtain();
                        message.what = PRINT_RESULT;
                        message.obj = result;
                        mHandler.sendMessage(message);
                    });
                } else {
                    showShort("请先下载PDF文件!");
                }
            });
        });
    }

    GetStateListener getStateListener;

    interface GetStateListener {
        void backState(String msg);
    }

    class PrintStep1Holder {
        LinearLayout print_step1;
        RecyclerView device_rv;
        LinearLayout progress_bar_layout;
        LinearLayout rescan_device_layout;
        Button rescan_device_btn;
        ImageView close_dialog_iv1;
        DevicesAdapter devicesAdapter;

        public PrintStep1Holder(View rootView) {
            print_step1 = rootView.findViewById(R.id.print_step1);
            device_rv = rootView.findViewById(R.id.device_rv);
            progress_bar_layout = rootView.findViewById(R.id.progress_bar_layout);
            rescan_device_layout = rootView.findViewById(R.id.rescan_device_layout);
            rescan_device_btn = rootView.findViewById(R.id.rescan_device_btn);
            close_dialog_iv1 = rootView.findViewById(R.id.close_dialog_iv1);
            rescan_device_btn.setOnClickListener(view -> {
                setRescanVisibility(View.GONE);
                setProgressVisibility(View.VISIBLE);
                bluetoothAdapter.startDiscovery();
            });
            close_dialog_iv1.setOnClickListener(view -> dismiss());
            initRecyclerView();
            setStep1Visibility(View.GONE);
            setRescanVisibility(View.GONE);
        }

        private void initRecyclerView() {
            devicesAdapter = new DevicesAdapter(getActivity(), bluetoothDevice -> {
                //第二步：连接打印机
                if (bluetoothDevice != null) {
                    showShort("连接打印机中...");
                    mHandler.post(() -> {
                        Message message = Message.obtain();
                        try {
                            connectRes = HPRTPrinterHelper.INSTANCE.connect(bluetoothDevice.getAddress());
                            message.what = CONNECT_RESULT;
                            message.arg1 = 0;
                        } catch (CustomerCodeException e) {
                            e.printStackTrace();
                            message.arg1 = -1;
                        }
                        mHandler.sendMessage(message);
                    });
                }
            });
            device_rv.setAdapter(devicesAdapter);
            device_rv.setLayoutManager(new LinearLayoutManager(getActivity()));
        }

        public void setStep1Visibility(int visible) {
            print_step1.setVisibility(visible);
        }

        public void setProgressVisibility(int visible) {
            progress_bar_layout.setVisibility(visible);
        }

        public void setRescanVisibility(int visible) {
            rescan_device_layout.setVisibility(visible);
        }
    }

    class PrintStep2Holder {
        LinearLayout print_step2;
        TextView blue_name_tv;
        TextView device_name_tv;
        TextView device_number_tv;
        TextView device_firmware_code_tv;
        TextView device_carbon_belt_tv;
        TextView device_carbon_belt_remain_tv;
        TextView device_state_tv;
        TextView device_electric_tv;
        TextView device_can_time_tv;
        TextView device_print_density_tv;
        TextView device_print_model_tv;
        TextView device_temperature_tv;
        TextView device_free_tv;
        TextView device_cache_state_tv;
        Button start_print_pdf_btn;
        ImageView close_dialog_iv2;

        public PrintStep2Holder(View rootView) {
            print_step2 = rootView.findViewById(R.id.print_step2);
            blue_name_tv = rootView.findViewById(R.id.blue_name_tv);
            //设备信息
            device_name_tv = rootView.findViewById(R.id.device_name_tv);
            device_number_tv = rootView.findViewById(R.id.device_number_tv);
            device_firmware_code_tv = rootView.findViewById(R.id.device_firmware_code_tv);
            device_carbon_belt_tv = rootView.findViewById(R.id.device_carbon_belt_tv);
            device_carbon_belt_remain_tv = rootView.findViewById(R.id.device_carbon_belt_remain_tv);
            //设备状态
            device_state_tv = rootView.findViewById(R.id.device_state_tv);
            device_electric_tv = rootView.findViewById(R.id.device_electric_tv);
            device_can_time_tv = rootView.findViewById(R.id.device_can_time_tv);
            device_print_density_tv = rootView.findViewById(R.id.device_print_density_tv);
            device_print_model_tv = rootView.findViewById(R.id.device_print_model_tv);
            device_temperature_tv = rootView.findViewById(R.id.device_temperature_tv);
            device_free_tv = rootView.findViewById(R.id.device_free_tv);
            device_cache_state_tv = rootView.findViewById(R.id.device_cache_state_tv);
            start_print_pdf_btn = rootView.findViewById(R.id.start_print_pdf_btn);
            close_dialog_iv2 = rootView.findViewById(R.id.close_dialog_iv2);
            start_print_pdf_btn.setOnClickListener(view -> startPrint());
            close_dialog_iv2.setOnClickListener(view -> dismiss());
            setStep2Visibility(View.GONE);
        }

        public void setStep2Visibility(int visible) {
            print_step2.setVisibility(visible);
        }

        public void setPrintBtnEnable(boolean enable) {
            start_print_pdf_btn.setEnabled(enable);
            start_print_pdf_btn.setText(enable ? "开始打印" : "开始打印（打印中）");
        }

        public void setInfoText(String text) {
            getActivity().runOnUiThread(() -> {
                if (info_flag == 1) device_name_tv.setText("设备名称：" + text);
                if (info_flag == 2) device_number_tv.setText("设备编号：" + text);
                if (info_flag == 3) device_firmware_code_tv.setText("固件版本：" + text);
                if (info_flag == 4) device_carbon_belt_tv.setText("碳带型号：" + text);
                if (info_flag == 5)
                    device_carbon_belt_remain_tv.setText("碳带剩余：" + text + " (单位:mm)");
                info_flag++;
                getDeviceInfo();
            });
        }
    }
}
